﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Utility;

namespace PolicyInjectionExtension
{
    /// <summary>
    /// A static facade class that provides the main entry point into the
    /// Policy Injection Application Block. Methods on this class
    /// create intercepted objects, or wrap existing instances with
    /// interceptors.
    /// </summary>
    public static class PolicyInjectionExtension
    {

        static PolicyInjectionExtension()
        {
            PolicyInjectionHelperFactory.SetupConfigureHelper(null);
        }

        #region Create Proxy Object
        /// <summary>
        /// Creates a new object of type <typeparamref name="TObject"/> and
        /// adds interception as needed to match the policies specified in
        /// the default policy configuration.
        /// </summary>
        /// <typeparam name="TObject">Type of object to create.</typeparam>
        /// <param name="args">Arguments to pass to the <typeparamref name="TObject"/> constructor.</param>
        /// <returns>The intercepted object (or possibly a raw instance if no policies apply).</returns>
        public static TObject Create<TObject>(params object[] args)
        {
            return PolicyInjectionHelperFactory.Helper.Create<TObject>(args);
        }

        /// <summary>
        /// Creates a new object of type <typeparamref name="TObject"/> and
        /// adds interception as needed to match the policies specified in
        /// the policy configuration supplied in <paramref name="configurationSource"/>.
        /// </summary>
        /// <typeparam name="TObject">Type of object to create.</typeparam>
        /// <param name="configurationSource"><see cref="IConfigurationSource"/> containing the policy configuration.</param>
        /// <param name="args">Arguments to pass to the <typeparamref name="TObject"/> constructor.</param>
        /// <returns>The intercepted object (or possibly a raw instance if no policies apply).</returns>
        public static TObject Create<TObject>(List<PolicyDataExtension> policies, params object[] args)
        {
            PolicyInjectionHelper policyInjector = PolicyInjectionHelperFactory.GetHelperFromPolicies(policies);
            return policyInjector.Create<TObject>(args);
        }

        public static TObject Create<TObject>(IConfigurationSource configurationSource, params object[] args)
        {
            PolicyInjectionHelper policyInjector = PolicyInjectionHelperFactory.GetHelperFromConfigure(configurationSource);
            return policyInjector.Create<TObject>(args);
        }

        /// <summary>
        /// Creates a new object of type <typeparamref name="TObject"/> and
        /// adds interception as needed to match the policies specified in
        /// the default policy configuration.
        /// </summary>
        /// <typeparam name="TObject">Concrete object type to create.</typeparam>
        /// <typeparam name="TInterface">Type of reference to return. Must be an interface the object implements.</typeparam>
        /// <param name="args">Arguments to pass to the <typeparamref name="TObject"/> constructor.</param>
        /// <returns>The intercepted object (or possibly a raw instance if no policies apply).</returns>
        public static TInterface Create<TObject, TInterface>(params object[] args)
        {
            return PolicyInjectionHelperFactory.Helper.Create<TObject, TInterface>(args);
        }

        /// <summary>
        /// Creates a new object of type <typeparamref name="TObject"/> and
        /// adds interception as needed to match the policies specified in
        /// the policy configuration supplied in <paramref name="configurationSource"/>.
        /// </summary>
        /// <typeparam name="TObject">Concrete object type to create.</typeparam>
        /// <typeparam name="TInterface">Type of reference to return. Must be an interface the object implements.</typeparam>
        /// <param name="configurationSource"><see cref="IConfigurationSource"/> containing the policy configuration.</param>
        /// <param name="args">Arguments to pass to the <typeparamref name="TObject"/> constructor.</param>
        /// <returns>The intercepted object (or possibly a raw instance if no policies apply).</returns>
        public static TInterface Create<TObject, TInterface>(List<PolicyDataExtension> policies, params object[] args)
        {
            PolicyInjectionHelper policyInjector = PolicyInjectionHelperFactory.GetHelperFromPolicies(policies);
            return policyInjector.Create<TObject, TInterface>(args);
        }

        public static TInterface Create<TObject, TInterface>(IConfigurationSource configurationSource, params object[] args)
        {
            PolicyInjectionHelper policyInjector = PolicyInjectionHelperFactory.GetHelperFromConfigure(configurationSource);
            return policyInjector.Create<TObject, TInterface>(args);
        }
        #endregion

        #region Wrap Object To Proxy
        /// <summary>
        /// Creates a proxy for the given object that adds interception policies as
        /// defined in the default configuration source.
        /// </summary>
        /// <remarks>
        /// Despite the name of the <typeparamref name="TInterface"/> parameter, this
        /// may be any type that the instance is assignable to, including both interfaces
        /// that it implements and the concrete type of the object.
        /// </remarks>
        /// <typeparam name="TInterface">Type of the proxy to return.</typeparam>
        /// <param name="instance">Instance object to wrap.</param>
        /// <returns>The proxy for the instance, or the raw object if no policies apply.</returns>
        public static TInterface Wrap<TInterface>(object instance)
        {
            return PolicyInjectionHelperFactory.Helper.Wrap<TInterface>(instance);
        }

        /// <summary>
        /// Creates a proxy for the given object that adds interception policies as
        /// defined in <paramref name="configurationSource"/>.
        /// </summary>
        /// <remarks>
        /// Despite the name of the <typeparamref name="TInterface"/> parameter, this
        /// may be any type that the instance is assignable to, including both interfaces
        /// that it implements and the concrete type of the object.
        /// </remarks>
        /// <typeparam name="TInterface">Type of the proxy to return.</typeparam>
        /// <param name="configurationSource"><see cref="IConfigurationSource"/> containing the policy configuration.</param>
        /// <param name="instance">Instance object to wrap.</param>
        /// <returns>The proxy for the instance, or the raw object if no policies apply.</returns>
        public static TInterface Wrap<TInterface>(List<PolicyDataExtension> policies, object instance)
        {
            PolicyInjectionHelper policyInjector = PolicyInjectionHelperFactory.GetHelperFromPolicies(policies);
            return policyInjector.Wrap<TInterface>(instance);
        }

        public static TInterface Wrap<TInterface>(IConfigurationSource configurationSource, object instance)
        {
            PolicyInjectionHelper policyInjector = PolicyInjectionHelperFactory.GetHelperFromConfigure(configurationSource);
            return policyInjector.Wrap<TInterface>(instance);
        }
        #endregion

       

        
    }
}
